using CollabApp.Domain.Entities.Game;

namespace CollabApp.Domain.Services.Game;

/// <summary>
/// 游戏广播服务接口
/// 负责实时推送游戏状态变化、事件通知和玩家互动信息
/// </summary>
public interface IGameBroadcastService
{
    /// <summary>
    /// 广播游戏状态更新
    /// 向所有游戏参与者推送游戏状态的变化
    /// </summary>
    /// <param name="gameId">游戏标识</param>
    /// <param name="stateUpdate">状态更新信息</param>
    /// <returns>广播是否成功</returns>
    Task<bool> BroadcastGameStateUpdateAsync(Guid gameId, GameStateUpdate stateUpdate);

    /// <summary>
    /// 广播玩家行为
    /// 向其他玩家推送某个玩家的行为信息
    /// </summary>
    /// <param name="gameId">游戏标识</param>
    /// <param name="playerAction">玩家行为信息</param>
    /// <param name="excludePlayerId">排除的玩家ID（通常是行为发起者）</param>
    /// <returns>广播是否成功</returns>
    Task<bool> BroadcastPlayerActionAsync(Guid gameId, PlayerActionBroadcast playerAction, Guid? excludePlayerId = null);

    /// <summary>
    /// 广播游戏事件
    /// 推送重要的游戏事件给相关玩家
    /// </summary>
    /// <param name="gameId">游戏标识</param>
    /// <param name="gameEvent">游戏事件</param>
    /// <param name="targetPlayers">目标玩家列表，为空则广播给所有人</param>
    /// <returns>广播是否成功</returns>
    Task<bool> BroadcastGameEventAsync(Guid gameId, GameEventBroadcast gameEvent, List<Guid>? targetPlayers = null);

    /// <summary>
    /// 发送私人消息
    /// 向特定玩家发送私人消息或通知
    /// </summary>
    /// <param name="gameId">游戏标识</param>
    /// <param name="playerId">目标玩家标识</param>
    /// <param name="message">消息内容</param>
    /// <returns>发送是否成功</returns>
    Task<bool> SendPrivateMessageAsync(Guid gameId, Guid playerId, PrivateMessage message);

    /// <summary>
    /// 广播计分更新
    /// 推送计分变化和排名更新
    /// </summary>
    /// <param name="gameId">游戏标识</param>
    /// <param name="scoreUpdate">计分更新信息</param>
    /// <returns>广播是否成功</returns>
    Task<bool> BroadcastScoreUpdateAsync(Guid gameId, ScoreUpdateBroadcast scoreUpdate);

    /// <summary>
    /// 广播地图变化
    /// 推送地图状态的变化（如领土变更、物品刷新等）
    /// </summary>
    /// <param name="gameId">游戏标识</param>
    /// <param name="mapUpdate">地图更新信息</param>
    /// <returns>广播是否成功</returns>
    Task<bool> BroadcastMapUpdateAsync(Guid gameId, MapUpdateBroadcast mapUpdate);

    /// <summary>
    /// 广播玩家状态变化
    /// 推送玩家状态的变化（如血量、位置、装备等）
    /// </summary>
    /// <param name="gameId">游戏标识</param>
    /// <param name="playerUpdate">玩家状态更新</param>
    /// <returns>广播是否成功</returns>
    Task<bool> BroadcastPlayerStatusUpdateAsync(Guid gameId, PlayerStatusUpdate playerUpdate);

    /// <summary>
    /// 广播系统通知
    /// 发送系统级别的通知消息
    /// </summary>
    /// <param name="gameId">游戏标识</param>
    /// <param name="notification">系统通知</param>
    /// <param name="targetPlayers">目标玩家，为空则发送给所有人</param>
    /// <returns>广播是否成功</returns>
    Task<bool> BroadcastSystemNotificationAsync(Guid gameId, SystemNotification notification, List<Guid>? targetPlayers = null);

    /// <summary>
    /// 加入游戏房间
    /// 将玩家连接添加到游戏房间的广播组
    /// </summary>
    /// <param name="connectionId">连接标识</param>
    /// <param name="gameId">游戏标识</param>
    /// <param name="playerId">玩家标识</param>
    /// <returns>操作是否成功</returns>
    Task<bool> JoinGameRoomAsync(string connectionId, Guid gameId, Guid playerId);

    /// <summary>
    /// 离开游戏房间
    /// 从游戏房间的广播组中移除玩家连接
    /// </summary>
    /// <param name="connectionId">连接标识</param>
    /// <param name="gameId">游戏标识</param>
    /// <param name="playerId">玩家标识</param>
    /// <returns>操作是否成功</returns>
    Task<bool> LeaveGameRoomAsync(string connectionId, Guid gameId, Guid playerId);

    /// <summary>
    /// 获取游戏房间在线玩家
    /// 获取当前在游戏房间中的所有在线玩家
    /// </summary>
    /// <param name="gameId">游戏标识</param>
    /// <returns>在线玩家列表</returns>
    Task<List<OnlinePlayer>> GetOnlinePlayersAsync(Guid gameId);
}

/// <summary>
/// 游戏状态更新广播
/// </summary>
public class GameStateUpdate
{
    public Guid GameId { get; set; }
    public Entities.Game.GameStatus Status { get; set; }
    public DateTime Timestamp { get; set; }
    public TimeSpan? RemainingTime { get; set; }
    public int Round { get; set; }
    public Dictionary<string, object> StateData { get; set; } = new();
}

/// <summary>
/// 玩家行为广播
/// </summary>
public class PlayerActionBroadcast
{
    public Guid PlayerId { get; set; }
    public string PlayerName { get; set; } = string.Empty;
    public ActionType ActionType { get; set; }
    public Position? Position { get; set; }
    public Position? TargetPosition { get; set; }
    public Guid? TargetPlayerId { get; set; }
    public DateTime Timestamp { get; set; }
    public Dictionary<string, object> ActionData { get; set; } = new();
}

/// <summary>
/// 游戏事件广播
/// </summary>
public class GameEventBroadcast
{
    public string EventType { get; set; } = string.Empty;
    public string Title { get; set; } = string.Empty;
    public string Message { get; set; } = string.Empty;
    public EventPriority Priority { get; set; }
    public Guid? RelatedPlayerId { get; set; }
    public Position? Location { get; set; }
    public DateTime Timestamp { get; set; }
    public Dictionary<string, object> EventData { get; set; } = new();
}

/// <summary>
/// 私人消息
/// </summary>
public class PrivateMessage
{
    public Guid SenderId { get; set; }
    public string SenderName { get; set; } = string.Empty;
    public string Content { get; set; } = string.Empty;
    public MessageType MessageType { get; set; }
    public DateTime Timestamp { get; set; }
    public Dictionary<string, object> Metadata { get; set; } = new();
}

/// <summary>
/// 计分更新广播
/// </summary>
public class ScoreUpdateBroadcast
{
    public Guid GameId { get; set; }
    public List<PlayerScoreUpdate> PlayerScores { get; set; } = new();
    public List<PlayerRanking> Rankings { get; set; } = new();
    public DateTime Timestamp { get; set; }
}

/// <summary>
/// 玩家计分更新
/// </summary>
public class PlayerScoreUpdate
{
    public Guid PlayerId { get; set; }
    public string PlayerName { get; set; } = string.Empty;
    public int PreviousScore { get; set; }
    public int CurrentScore { get; set; }
    public int ScoreChange { get; set; }
    public string Reason { get; set; } = string.Empty;
}

/// <summary>
/// 地图更新广播
/// </summary>
public class MapUpdateBroadcast
{
    public Guid GameId { get; set; }
    public MapUpdateType UpdateType { get; set; }
    public Position? Position { get; set; }
    public float? Radius { get; set; }
    public Guid? OwnerId { get; set; }
    public string? ItemId { get; set; }
    public DateTime Timestamp { get; set; }
    public Dictionary<string, object> UpdateData { get; set; } = new();
}

/// <summary>
/// 玩家状态更新
/// </summary>
public class PlayerStatusUpdate
{
    public Guid PlayerId { get; set; }
    public string PlayerName { get; set; } = string.Empty;
    public Position Position { get; set; } = new();
    public float Health { get; set; }
    public float MaxHealth { get; set; }
    public PlayerState State { get; set; }
    public List<string> ActiveEffects { get; set; } = new();
    public DateTime Timestamp { get; set; }
    public Dictionary<string, object> CustomStatus { get; set; } = new();
}

/// <summary>
/// 系统通知
/// </summary>
public class SystemNotification
{
    public string Id { get; set; } = string.Empty;
    public string Title { get; set; } = string.Empty;
    public string Message { get; set; } = string.Empty;
    public NotificationType Type { get; set; }
    public EventPriority Priority { get; set; }
    public TimeSpan? DisplayDuration { get; set; }
    public DateTime Timestamp { get; set; }
    public Dictionary<string, object> Data { get; set; } = new();
}

/// <summary>
/// 在线玩家信息
/// </summary>
public class OnlinePlayer
{
    public Guid PlayerId { get; set; }
    public string PlayerName { get; set; } = string.Empty;
    public string ConnectionId { get; set; } = string.Empty;
    public DateTime ConnectedAt { get; set; }
    public PlayerState State { get; set; }
    public bool IsReady { get; set; }
}

/// <summary>
/// 事件优先级
/// </summary>
public enum EventPriority
{
    Low,
    Normal,
    High,
    Critical
}

/// <summary>
/// 消息类型
/// </summary>
public enum MessageType
{
    Chat,
    System,
    Achievement,
    Warning,
    Info
}

/// <summary>
/// 地图更新类型
/// </summary>
public enum MapUpdateType
{
    TerritoryChanged,
    ItemSpawned,
    ItemRemoved,
    ObstacleAdded,
    ObstacleRemoved,
    EffectApplied,
    EffectRemoved
}

/// <summary>
/// 玩家状态
/// </summary>
public enum PlayerState
{
    Waiting,
    Ready,
    Playing,
    Dead,
    Spectating,
    Disconnected
}

/// <summary>
/// 通知类型
/// </summary>
public enum NotificationType
{
    Info,
    Success,
    Warning,
    Error,
    Achievement
}
